<?php

namespace app\common\service;

use app\common\model\collect\GoodsAttributeKeyModel;
use app\common\model\collect\GoodsAttributeModel;
use app\common\model\collect\GoodsAttributeValueModel;
use app\common\model\collect\GoodsImageModel;
use app\common\model\collect\GoodsModel;
use app\common\model\collect\GoodsSkuModel;
use think\admin\service\AdminService;
use think\facade\Db;

/**
 * 采集商品数据处理服务
 *
 * @Description
 * @package app\common\service
 * @author wangqinghui
 * @date 2024-10-24 17:29
 */
class CollectService
{

    // 采集地址来源
    protected $source = '';

    // 支持的采集来源
    protected $support_source = ['1688'];

    // 采集处理对象实例
    protected static $handler = null;

    // 采集组装数据
    protected $assember_goods_data = ['goods' => [], 'images' => [], 'attrs' => [], 'skus' => []];

    public function __construct()
    {
        
    }

    /**
     * 初始化服务
     *
     * @Description
     * @author wangqinghui
     * @date 2024-10-25 10:10
     * @param string $url
     * @return CollectService
     */
    public function init(string $url) : CollectService
    {
        if(empty($url)){
            throw new \Exception('采集地址有误');
        }

        if(strpos($url, '1688.com') !== false){
            $this->setSource('1688');
        }

        if(!in_array($this->source, $this->support_source)){
            throw new \Exception('暂不支持该来源');
        }
        return $this;
    }

    /**
     * 设置采集来源
     *
     * @Description
     * @author wangqinghui
     * @date 2024-10-24 17:38
     * @param string $source
     * @return CollectService
     */
    protected function setSource(string $source) : CollectService
    {
        $this->source = $source;
        return $this;
    }


    /**
     * 实例化对应的采集处理类
     *
     * @Description
     * @author wangqinghui
     * @date 2024-10-24 17:39
     * @return void
     */
    protected function getInstance()
    {
        if (is_null(self::$handler)) {
            $class = '\\app\\common\\service\\collect\\Collect'.$this->source.'Service';
            self::$handler = new $class();
        }
        return self::$handler;
    }

    /**
     * 采集数据入库
     *
     * @Description
     * @author wangqinghui
     * @date 2024-10-25 09:38
     * @return boolean
     */
    public function addOrUpdateCollectData() : bool
    {
        if(empty($this->assember_goods_data['goods'])){
            throw new \Exception('未采集到有效数据');
        }
        // 判断数据是否存在
        $map = [
            ['goods_code', '=', $this->assember_goods_data['goods']['goods_code']],
            ['from', '=', $this->assember_goods_data['goods']['platform']],
            ['user_id', '=', AdminService::getUserId()]
        ];
        $goods_info = GoodsModel::mk()->field('id,is_claim,spu_code')->where($map)->find();
        $edit_goods_id = $goods_info['id'] ?? 0;
        if(!empty($goods_info['is_claim']) && ($goods_info['is_claim'] == 1)){
            throw new \Exception('该商品已被认领');
        }

        // 启动事务
        Db::startTrans();
        try {
            // 添加商品基本信息
            $collect_url = !empty($this->assember_goods_data['goods']['url']) ? $this->assember_goods_data['goods']['url'] : '';
            $add_goods_base = [
                'from'  =>  !empty($this->assember_goods_data['goods']['platform']) ? $this->assember_goods_data['goods']['platform'] : 0,
                'collect_url'   =>    $collect_url,// 采集地址
                'md5_url'       =>    md5($collect_url),
                'title'         =>    !empty($this->assember_goods_data['goods']['title']) ? $this->assember_goods_data['goods']['title'] : '',// 商品标题
                'desc'          =>    !empty($this->assember_goods_data['goods']['desc']) ? $this->assember_goods_data['goods']['desc'] : '',// 商品描述
                'detail'        =>    !empty($this->assember_goods_data['goods']['detail']) ? $this->assember_goods_data['goods']['detail'] : '',// 商品详情
                'goods_code'    =>    !empty($this->assember_goods_data['goods']['goods_code']) ? $this->assember_goods_data['goods']['goods_code'] : '',// 采集商品ID
                'user_id'       =>  AdminService::getUserId(), // 用户ID 
                'account_id'    =>  AdminService::getAccountId(), // 账号所属公司
                //'price'         => !empty($this->assember_goods_data['goods']['price']) ? $this->assember_goods_data['goods']['price'] : '',// 商品价格
                'min_price'     =>  !empty($this->assember_goods_data['goods']['min_price']) ? $this->assember_goods_data['goods']['min_price'] : 0.00,// 最低价格
                'max_price'     =>  !empty($this->assember_goods_data['goods']['max_price']) ? $this->assember_goods_data['goods']['max_price'] : 0.00,// 最高价格'
                'shop_name'     =>  !empty($this->assember_goods_data['goods']['shop_name']) ? $this->assember_goods_data['goods']['shop_name'] : '',// 店铺名称
                'category_code' =>  !empty($this->assember_goods_data['goods']['category_code']) ? $this->assember_goods_data['goods']['category_code'] : '',// 商品类目编码
                'category_name' =>  !empty($this->assember_goods_data['goods']['category_name'])? $this->assember_goods_data['goods']['category_name'] : '',// 商品类目名称
                'spu_code'      => $goods_info['spu_code'] ?? '',
                'main_pic'      => !empty($this->assember_goods_data['images'][0])? $this->assember_goods_data['images'][0] : '', // 主图
            ];
            if(empty($edit_goods_id)){
                // 获取当天产品总数量
                $map = [
                    ['create_at', '>=', date('Y-m-d 00:00:00')],
                    ['create_at', '<=', date('Y-m-d 23:59:59')],
                ];
                $day_goods_count = GoodsModel::mk()->where('create_at', '>=', date('Y-m-d 00:00:00'))->count('id');
                $spu_code = date('Ymd').str_pad($day_goods_count+1, 6, '0', STR_PAD_LEFT);
                $add_goods_base['spu_code'] = $spu_code;// 商品编码
            }
            // 修改商品信息
            if(!empty($edit_goods_id)){
                $goods_count = GoodsModel::mk()->where('id', $edit_goods_id)->update($add_goods_base);
                if($goods_count < 0){
                    throw new \Exception('商品更新失败');
                }
                $goods_id = $edit_goods_id;
            }else{
                // 添加商品信息
                $goods_id = GoodsModel::mk()->insertGetId($add_goods_base);
                if(empty($goods_id) || ($goods_id <= 0)){
                    throw new \Exception('商品添加失败');
                }
            }
            // 添加商品图片
            if(!empty($this->assember_goods_data['images'])){
                $add_img_data = [];
                foreach ($this->assember_goods_data['images'] as $imgItem){
                    $add_img_data[] = [
                        'goods_id'  =>  $goods_id,
                        'image'   =>  $imgItem,// 商品图片
                    ];
                }
                if(!empty($edit_goods_id)){
                    // 先删除商品图片
                    $delete_count = GoodsImageModel::mk()->where('goods_id', $edit_goods_id)->delete();
                    // if($delete_count <= 0){
                    //     throw new \Exception('商品图片更新失败');
                    // }
                }
                $img_count = GoodsImageModel::mk()->insertAll($add_img_data);
                if(empty($img_count) || ($img_count <= 0)){
                    throw new \Exception('商品图片添加失败');
                }
            }

            // // 添加商品属性名称和属性值
            // if(!empty($this->assember_goods_data['attrs'])){
            //     if(!empty($edit_goods_id)){
            //         // 删除商品属性名称
            //         $atrr_key_del_count = GoodsAttributeKeyModel::mk()->where('goods_id', $edit_goods_id)->delete();
            //         if($atrr_key_del_count <= 0){
            //             throw new \Exception('商品属性名称更新失败');
            //         }
            //         // 删除商品属性值
            //         $atrr_value_del_count = GoodsAttributeValueModel::mk()->where('goods_id', $edit_goods_id)->delete();
            //         if($atrr_value_del_count <= 0){
            //             throw new \Exception('商品属性值更新失败');
            //         }
            //     }
            //     // 添加商品属性名称
            //     $add_attr_value_data = [];
            //     foreach ($this->assember_goods_data['attrs'] as $key => $value){
            //         $add_attr_name_data = [
            //             'goods_id'      =>  $goods_id,
            //             'key_name'      =>  $key,// 属性名称
            //         ];
            //         $attr_key_id = GoodsAttributeKeyModel::mk()->insertGetId($add_attr_name_data);
            //         if(empty($attr_key_id) || ($attr_key_id <= 0)){
            //             throw new \Exception('商品属性名称添加失败');
            //         }
            //         if(!empty($value) && is_array($value)){
            //             foreach ($value as $item){
            //                 $add_attr_value_data[] = [
            //                     'goods_id'      =>  $goods_id,
            //                     'key_id'        =>  $attr_key_id,// 属性名称ID
            //                     'value_name'    =>  $item['name'] ?? '',// 属性值
            //                     'image'         =>  $item['imageUrl'] ?? '',// 属性图片
            //                 ];
            //             }
            //         }
            //     }
            //     if(!empty($add_attr_value_data)){
            //         $attr_count = GoodsAttributeValueModel::mk()->insertAll($add_attr_value_data);
            //         if(empty($attr_count) || ($attr_count <= 0)){
            //             throw new \Exception('商品属性值添加失败');
            //         }
            //     }
            // }

            // 添加商品属性
            if(!empty($this->assember_goods_data['attrs'])){
                $add_attr_data = [];
                foreach ($this->assember_goods_data['attrs'] as $key => $value){
                    if(!empty($value) && is_array($value)){
                        foreach ($value as $item){
                            $add_attr_data[] = [
                                'goods_id'      =>  $goods_id,
                                'key_name'      =>  $key,// 属性名称
                                'value_name'    =>  $item['name'] ?? '',// 属性值
                                'image'         =>  $item['imageUrl'] ?? '',// 属性图片
                            ];
                        }
                    }
                }
                if(!empty($edit_goods_id)){
                    // 删除商品属性
                    $atrr_del_count = GoodsAttributeModel::mk()->where('goods_id', $edit_goods_id)->delete();
                    // if($atrr_del_count <= 0){
                    //     throw new \Exception('商品属性修改失败');
                    // }
                }
                $attr_count = GoodsAttributeModel::mk()->insertAll($add_attr_data);
                if(empty($attr_count) || ($attr_count <= 0)){
                    throw new \Exception('商品属性添加失败');
                }
            }
            
            // 添加商品sku
            if(!empty($this->assember_goods_data['skus'])){
                $add_sku_data = [];
                // 获取商品sku属性
                $sku_attr_arr = array_column($this->assember_goods_data['skus'], 'specAttrs');
                $attr_ids_data = [];
                if(!empty($sku_attr_arr)){
                    $sku_attr_str = implode('&gt;', $sku_attr_arr);
                    $sku_attr_data = explode('&gt;', $sku_attr_str);
                    $map = [
                        ['goods_id', '=', $goods_id],
                        ['value_name', 'in', $sku_attr_data],
                    ];
                    //$attr_ids_data = GoodsAttributeValueModel::mk()->where($map)->column('id', 'value_name');
                    $attr_ids_data = GoodsAttributeModel::mk()->where($map)->column('id', 'value_name');
                }
                foreach ($this->assember_goods_data['skus'] as $skuItem){
                    $specAttrsArr = !empty($skuItem['specAttrs']) ? explode('&gt;', $skuItem['specAttrs']) : [];
                    $attribute_ids = [];
                    foreach ($specAttrsArr as $key => $value){
                        if(!empty($attr_ids_data[$value])){
                            $attribute_ids[] = $attr_ids_data[$value];
                        }
                    }
                    $add_sku_data[] = [
                        'sku_code'  =>  $skuItem['skuId'] ?? '',// 采集商品skuID
                        'goods_id'  =>  $goods_id,// 商品ID
                        'image'     =>  $skuItem['skuImage'] ?? '',// sku图片
                        'price'     =>  $skuItem['pe_price'] ?? 0.00,// sku价格
                        'length'    =>  $skuItem['length'] ?? 0.00,// 商品长度
                        'width'     =>  $skuItem['width'] ?? 0.00,// 商品宽度
                        'height'    =>  $skuItem['height'] ?? 0.00,// 商品高度
                        'weight'    =>  $skuItem['weight'] ?? 0.00,// 商品重量(g)
                        'volume'    =>  $skuItem['volume'] ?? 0.000,// 商品体积(cm³)
                        'stock'     =>  $skuItem['stock'] ?? 0,// 商品库存
                        'attribute_ids' =>  implode(',', $attribute_ids),
                        'title'     =>  $add_goods_base['spu_code'].'-'.$skuItem['title'],// sku标题
                        'attribute_titles' => implode(',', $specAttrsArr), // sku属性值合集
                    ];
                }
                if(!empty($edit_goods_id)){
                    // 删除商品sku
                    $sku_del_count = GoodsSkuModel::mk()->where('goods_id', $edit_goods_id)->delete();
                    if($sku_del_count <= 0){
                        throw new \Exception('商品sku删除失败');
                    }
                }
                $add_sku_count = GoodsSkuModel::mk()->insertAll($add_sku_data);
                if(empty($add_sku_count) || ($add_sku_count <= 0)){
                    throw new \Exception('商品sku添加失败');
                }
            }
            // 提交事务
            Db::commit();
        } catch (\Exception $th) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($th->getMessage());
        }
        return true;
    }


    /**
     * 调用采集处理类方法
     *
     * @Description
     * @author wangqinghui
     * @date 2024-10-24 17:56
     * @param string $method
     * @param mixed $args
     * @return void
     */
    public function __call(string $method, mixed $args)
    {
        return call_user_func_array([$this->getInstance(), $method], $args);
    }
}